import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:focus_detector_v2/focus_detector_v2.dart';
import 'package:openim_common/openim_common.dart';
import 'package:openim_common/src/widgets/chat/chat_card_view.dart';
import 'package:openim_common/src/widgets/chat/chat_file_view.dart';
import 'package:openim_common/src/widgets/chat/chat_message_menu.dart';
import 'package:openim_common/src/widgets/chat/chat_video_view.dart';
import 'package:openim_common/src/widgets/chat/chat_voice_view.dart';
import 'package:rxdart/rxdart.dart';
import 'chat_notice_view.dart';
import 'chat_quote_view.dart';
double maxWidth = 247.w;
double pictureWidth = 120.w;
double videoWidth = 120.w;
double locationWidth = 220.w;

BorderRadius borderRadius(bool isISend) => BorderRadius.only(
      topLeft: Radius.circular(isISend ? 6.r : 0),
      topRight: Radius.circular(isISend ? 0 : 6.r),
      bottomLeft: Radius.circular(6.r),
      bottomRight: Radius.circular(6.r),
    );

class MsgStreamEv<T> {
  final String id;
  final T value;

  MsgStreamEv({required this.id, required this.value});

  @override
  String toString() {
    return 'MsgStreamEv{msgId: $id, value: $value}';
  }
}

class CustomTypeInfo {
  final Widget customView;
  final bool needBubbleBackground;
  final bool needChatItemContainer;

  CustomTypeInfo(
    this.customView, [
    this.needBubbleBackground = true,
    this.needChatItemContainer = true,
  ]);
}

typedef CustomTypeBuilder = CustomTypeInfo? Function(
  BuildContext context,
  Message message,
);
typedef NotificationTypeBuilder = Widget? Function(
  BuildContext context,
  Message message,
);
typedef ItemViewBuilder = Widget? Function(
  BuildContext context,
  Message message,
);
typedef ItemVisibilityChange = void Function(
  Message message,
  bool visible,
);

class ChatItemView extends StatefulWidget {
  const ChatItemView({
    Key? key,
    this.mediaItemBuilder,
    this.itemViewBuilder,
    this.customTypeBuilder,
    this.notificationTypeBuilder,
    this.sendStatusSubject,
    this.visibilityChange,
    this.timelineStr,
    this.leftNickname,
    this.leftFaceUrl,
    this.rightNickname,
    this.rightFaceUrl,
    required this.message,
    this.textScaleFactor = 1.0,
    this.ignorePointer = false,
    this.showLeftNickname = true,
    this.showRightNickname = false,
    this.highlightColor,
    this.allAtMap = const {},
    this.patterns = const [],
    this.onTapLeftAvatar,
    this.onTapRightAvatar,
    this.onLongPressRightAvatar,
    this.onVisibleTrulyText,
    this.onFailedToResend,
    this.onClickItemView,
    required this.onTapUserProfile,
    this.onCopyMessage,
    this.onQuoteMessage,
    this.onDeleteMessage,
    this.onRevokeMessage,
    this.onForwardMessage,
    this.onMultiSelectMessage,
    this.onPinMessage,
    // 多选相关参数
    this.isMultiSelectMode = false,
    this.isSelected = false,
    this.onToggleSelection,
    this.sendProgressSubject,
    this.isSingleChat = false, // 新增参数：是否为一对一私聊
    this.isMessagePinned = false, // 新增参数：该消息是否已置顶
    this.canPinMessage = false, // 新增参数：是否有置顶权限

  }) : super(key: key);
    
  final Subject<MsgStreamEv<int>>? sendProgressSubject; // 添加进度流参数
  final ItemViewBuilder? mediaItemBuilder;
  final ItemViewBuilder? itemViewBuilder;
  final CustomTypeBuilder? customTypeBuilder;
  final NotificationTypeBuilder? notificationTypeBuilder;

  final Subject<MsgStreamEv<bool>>? sendStatusSubject;

  final ItemVisibilityChange? visibilityChange;
  final String? timelineStr;
  final String? leftNickname;
  final String? leftFaceUrl;
  final String? rightNickname;
  final String? rightFaceUrl;
  final Message message;

  final double textScaleFactor;
  final bool ignorePointer;
  final bool showLeftNickname;
  final bool showRightNickname;

  final Color? highlightColor;
  final Map<String, String> allAtMap;
  final List<MatchPattern> patterns;
  final Function()? onTapLeftAvatar;
  final Function()? onTapRightAvatar;
  final Function()? onLongPressRightAvatar;
  final Function(String? text)? onVisibleTrulyText;
  final Function()? onClickItemView;
  final ValueChanged<({String userID, String name, String? faceURL, String? groupID})> onTapUserProfile;

  final Function()? onFailedToResend;

  final Function(Message message)? onCopyMessage;
  final Function(Message message)? onQuoteMessage;
  final Function(Message message)? onDeleteMessage;
  final Function(Message message)? onRevokeMessage;
  final Function(Message message)? onForwardMessage;
  final Function(Message message)? onMultiSelectMessage;
  final Function(Message message)? onPinMessage;

  // 多选相关参数
  final bool isMultiSelectMode;
  final bool isSelected;
  final Function(Message message)? onToggleSelection;
  final bool isSingleChat; // 新增参数：是否为一对一私聊
  final bool isMessagePinned; // 新增参数：该消息是否已置顶
  final bool canPinMessage; // 新增参数：是否有置顶权限

  @override
  State<ChatItemView> createState() => _ChatItemViewState();
}

class _ChatItemViewState extends State<ChatItemView> {
  Message get _message => widget.message;

  bool get _isISend => _message.sendID == OpenIM.iMManager.userID;
  final CustomPopupMenuController _menuController = CustomPopupMenuController();
  @override
  Widget build(BuildContext context) {
    return FocusDetector(
      child: Container(
        color: widget.highlightColor,
        margin: EdgeInsets.only(bottom: 20.h),
        padding: EdgeInsets.symmetric(horizontal: 10.w),
        child: Center(
          child: widget.isMultiSelectMode 
              ? _buildMultiSelectView()
              : _child,
        ),
      ),
      onVisibilityLost: () {
        widget.visibilityChange?.call(widget.message, false);
      },
      onVisibilityGained: () {
        widget.visibilityChange?.call(widget.message, true);
      },
    );
  }
   // 构建多选模式下的视图
  Widget _buildMultiSelectView() {
    // 如果是通知消息，不显示选择框，直接显示消息内容
    if (_message.isNotificationType) {
      return _child;
    }
    
    // 检查是否为置顶相关的自定义消息
    if (_message.isCustomType) {
      final data = IMUtils.parseCustomMessage(_message);
      if (data != null) {
        final customType = data['viewType'];
        if (customType == CustomMessageType.pinMessage || 
            customType == CustomMessageType.unpinMessage) {
          return _child; // 置顶相关消息不显示选择框
        }
      }
    }
    
    return GestureDetector(
      onTap: () => widget.onToggleSelection?.call(_message),
      child: Row(
        children: [
          // 选择框
          Container(
            width: 24.w,
            height: 24.w,
            margin: EdgeInsets.only(right: 10.w),
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              border: Border.all(
                color: widget.isSelected ? Styles.c_0089FF : Styles.c_8E9AB0,
                width: 2.w,
              ),
              color: widget.isSelected ? Styles.c_0089FF : Colors.transparent,
            ),
            child: widget.isSelected
                ? Icon(
                    Icons.check,
                    size: 16.w,
                    color: Colors.white,
                  )
                : null,
          ),
          // 消息内容
          Expanded(child: _child),
        ],
      ),
    );
  }
 
  Widget get _child => widget.itemViewBuilder?.call(context, _message) ?? _buildChildView();

  Widget _buildChildView() {
    Widget? child;
    String? senderNickname;
    String? senderFaceURL;
    bool isBubbleBg = false;
    /* if (_message.isCallType) {
    } else if (_message.isMeetingType) {
    } else if (_message.isDeletedByFriendType) {
    } else if (_message.isBlockedByFriendType) {
    } else if (_message.isEmojiType) {
    } else if (_message.isTagType) {
    }*/
    if (_message.isTextType) {
      isBubbleBg = true;
      child = ChatText(
        text: _message.textElem!.content!,
        patterns: widget.patterns,
        textScaleFactor: widget.textScaleFactor,
        onVisibleTrulyText: widget.onVisibleTrulyText,
      );
    }else if (_message.contentType == MessageType.quote) {
      // 引用消息类型
      isBubbleBg = true;
      child = ChatQuoteView(
        message: _message,
        isISend: _isISend,
        onTapQuotedMessage: (quotedMessage) {
          // 可以添加跳转到原消息的逻辑
          // 例如：滚动到原消息位置
        },
      );
    } else if (_message.isPictureType) {
      child = widget.mediaItemBuilder?.call(context, _message) ??
          ChatPictureView(
            isISend: _isISend,
            message: _message,
          );
    } else if (_message.isVideoType) {
      debugPrint('_buildChildView 视频时长: ${_message.videoElem!.duration}');
      // 添加视频消息处理
      child = widget.mediaItemBuilder?.call(context, _message) ??
          ChatVideoView(
            isISend: _isISend,
            message: _message,
            sendProgressStream: widget.sendProgressSubject?.stream,
            isMultiSelectMode: widget.isMultiSelectMode,
            onToggleSelection: widget.onToggleSelection,
          );
    } else if (_message.isVoiceType) {
      isBubbleBg = true;
       child = ChatVoiceView(
        isISend: _isISend,
        message: _message,
      );
    } else if (_message.isFileType) {
      isBubbleBg = true;
      child = ChatFileView(
        isISend: _isISend,
        message: _message,
        downloadProgressStream: widget.sendProgressSubject?.stream,
      );
    } else if (_message.contentType == MessageType.card) {
      // 名片消息类型
      isBubbleBg = true;
      child = ChatCardView(
        message: _message,
        isISend: _isISend,
        isMultiSelectMode: widget.isMultiSelectMode,
        onToggleSelection: widget.onToggleSelection,
        onTapCard: (userID, nickname, faceURL) {
          // 点击名片跳转到用户资料页
          widget.onTapUserProfile.call((
            userID: userID,
            name: nickname,
            faceURL: faceURL,
            groupID: null,
          ));
        },
      );
    } 
    else if (_message.isNotificationType) {
      if (_message.contentType == MessageType.groupInfoSetAnnouncementNotification) {
        final map = json.decode(_message.notificationElem!.detail!);
        final ntf = GroupNotification.fromJson(map);
        final noticeContent = ntf.group?.notification;
        senderNickname = ntf.opUser?.nickname;
        senderFaceURL = ntf.opUser?.faceURL;
        child = ChatNoticeView(isISend: _isISend, content: noticeContent!);
      } else {
        return ConstrainedBox(
          constraints: BoxConstraints(maxWidth: maxWidth),
          child: ChatHintTextView(
            message: _message,
            onTapUserProfile: widget.onTapUserProfile,
          ),
        );
      }
    } else if (_message.isCustomType) {
      // 处理自定义消息类型
      final customTypeInfo = widget.customTypeBuilder?.call(context, _message);
      if (customTypeInfo != null) {
        isBubbleBg = customTypeInfo.needBubbleBackground;
        child = customTypeInfo.customView;
        
        // 如果不需要 ChatItemContainer，直接返回自定义视图
        if (!customTypeInfo.needChatItemContainer) {
          return customTypeInfo.customView;
        }
      } else {
        // 如果没有自定义构建器，使用默认处理
        final data = IMUtils.parseCustomMessage(_message);
        if (data != null) {
          final customType = data['customType'];
          switch (customType) {
            case CustomMessageType.call:
              isBubbleBg = true;
              final type = data['type'];
              final content = data['content'];
              child = ChatCallItemView(type: type, content: content);
              break;
            default:
              isBubbleBg = true;
              child = ChatText(text: '[${StrRes.unsupportedMessage}]');
              break;
          }
        } else {
          isBubbleBg = true;
          child = ChatText(text: '[${StrRes.unsupportedMessage}]');
        }
      }
    } 

    senderNickname ??= widget.leftNickname ?? _message.senderNickname;
    senderFaceURL ??= widget.leftFaceUrl ?? _message.senderFaceUrl;

     // 包装消息内容，添加长按菜单
    final messageContent = ChatMessageMenu(
      message: _message,
      isISend: _isISend,
      controller: _menuController,
      onCopyMessage: widget.onCopyMessage,
      onQuoteMessage: widget.onQuoteMessage,
      onDeleteMessage: widget.onDeleteMessage,
      onRevokeMessage: widget.onRevokeMessage,
      onForwardMessage: widget.onForwardMessage,
      onMultiSelectMessage: widget.onMultiSelectMessage,
      onPinMessage: widget.onPinMessage,
      isSingleChat: widget.isSingleChat, // 传递聊天类型信息
      isMessagePinned: widget.isMessagePinned, // 传递该消息是否已置顶
      isMultiSelectMode: widget.isMultiSelectMode, // 传递多选模式状态
      canPinMessage: widget.canPinMessage, // 传递置顶权限信息
      child: GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: widget.isMultiSelectMode 
            ? () => widget.onToggleSelection?.call(_message)
            : widget.onClickItemView,
        child: child ?? ChatText(text: StrRes.unsupportedMessage),
      ),
    );
    
    return child = ChatItemContainer(
      id: _message.clientMsgID!,
      isISend: _isISend,
      leftNickname: senderNickname,
      leftFaceUrl: senderFaceURL,
      rightNickname: widget.rightNickname ?? OpenIM.iMManager.userInfo.nickname,
      rightFaceUrl: widget.rightFaceUrl ?? OpenIM.iMManager.userInfo.faceURL,
      showLeftNickname: widget.showLeftNickname,
      showRightNickname: widget.showRightNickname,
      timelineStr: widget.timelineStr,
      timeStr: IMUtils.getChatTimeline(_message.sendTime!, 'HH:mm:ss'),
      hasRead: _message.isRead!,
      isSending: _message.status == MessageStatus.sending, // 移除视频消息的特殊处理
      isSendFailed: _message.status == MessageStatus.failed,
      isBubbleBg: child == null ? true : isBubbleBg,
      ignorePointer: widget.ignorePointer,
      sendStatusStream: widget.sendStatusSubject,
      onFailedToResend: widget.onFailedToResend,
      onLongPressRightAvatar: widget.onLongPressRightAvatar,
      onTapLeftAvatar: widget.onTapLeftAvatar,
      onTapRightAvatar: widget.onTapRightAvatar,
      child: messageContent
    );
  }
}
